package com.atguigu.gmall.activity.consumer;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.activity.entity.SeckillOrder;
import com.atguigu.gmall.activity.entity.UserRecode;
import com.atguigu.gmall.activity.mapper.SeckillGoodsMapper;
import com.atguigu.gmall.activity.mapper.SeckillOrderMapper;
import com.atguigu.gmall.activity.service.SeckillService;
import com.atguigu.gmall.model.activity.SeckillGoods;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Map;

/**
 * 秒杀订单的监听类
 * @author 搭忆长安
 * @version 1.0
 * @date 2021年07月16日 23:50
 * @ClassName:SeckillOrderUpdateListener
 * @Description: TODO
 */
public class SeckillOrderUpdateListener {

    @Autowired
    private SeckillService seckillService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillOrderMapper seckillOrderMapper;

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;
    @RabbitListener(queues = "seckill_queue")
    public  void updateSeckillOrder(String msg){
        //将消息的类型转换为map类型的数据
        Map<String,String> payResult = JSONObject.parseObject(msg, Map.class);
        String payway = payResult.get("payway");
        if(payway.equals("0")){
            //支付宝支付逻辑
            Map<String,String> map = JSONObject.parseObject(msg, Map.class);
            //进行解析，获取请求的结果
            String tradeStatus = map.get("trade_status");
            if(!StringUtils.isEmpty(tradeStatus)&&tradeStatus.equals("TRADE_SUCCESS")){
              //支付成功，修改订单的状态
                seckillService.paySuccess(map);
                return;
            }else{
                //微信支付逻辑
                String returnCode = payResult.get("return_code");
                if(returnCode.equals("SUCCESS")){
                    //支付成功，修改订单的状态
                    seckillService.paySuccess(payResult);
                    return;
                }
            }
            //支付失败，修改订单的状态
            seckillService.payFail(payResult);
        }
    }
    /**
     * 监听超时未支付的订单的延迟消息:秒杀的下单服务发送的消息
     * @param msg
     */
    @RabbitListener(queues = "seckill_normal_queue")
    public  void cancleSeckillOrder(String msg){
      //数据类型的转换
        SeckillOrder seckillOrder = JSONObject.parseObject(msg, SeckillOrder.class);
        //取消订单
        //判断前置
        if(seckillOrder!=null&&seckillOrder.getStatus().equals("0")){
            //修改redis中订单的状态
            String username = seckillOrder.getUserId();
            redisTemplate.boundHashOps("SeckillOrder_" + username).put(seckillOrder.getId(), seckillOrder);
            //将订单的信息存入数据库
            seckillOrderMapper.insert(seckillOrder);
            //库存回滚----1.redis回滚，2.数据库回滚
            UserRecode userRecode = (UserRecode)redisTemplate.boundValueOps("SeckillStatus_" + username).get();
            rollBackSeckillGoodsNum(userRecode.getGoodsId(), userRecode.getTime(), userRecode.getNum());
            //排队标识删除掉
            redisTemplate.delete("SeckillUserQueue_" + username);
            //排队状态可以删掉了
            redisTemplate.delete("SeckillStatus_" + username);
        }
    }
    /**
     * 回滚秒杀商品的库存
     */
    private void rollBackSeckillGoodsNum(String skuId, String time, Integer num) {
        //从redis中获取商品的数据
        SeckillGoods seckillGoods =
                (SeckillGoods) redisTemplate.boundHashOps("SeckillGoods_" + time).get(skuId);
        if (seckillGoods == null) {
            //商品已经售罄了--更新数据库中的库存数据
            seckillGoodsMapper.updateSeckillGoodsStock(skuId, num);
        } else {
            //redis中还有数据--更新redis中的库存数据
            String[] seckillGoodsQueue = getSeckillGoodsQueue(skuId, num);
            redisTemplate.boundListOps("seckillGoodsQueue_" + skuId).leftPushAll(seckillGoodsQueue);
            //回滚库存的对象
            redisTemplate.boundHashOps("SeckillGoodsStockNum").increment(skuId, num);
        }
    }
    /**
     * 构建商品库存个数长度的数组
     * @param goodsId
     * @param stockCount
     * @return
     */
    private String[] getSeckillGoodsQueue(String goodsId, Integer stockCount){
        //构建一个库存长度的数组
        String[] ids = new String[stockCount];
        //元素填充
        for (int i = 0; i < stockCount; i++) {
            ids[i] = goodsId;
        }
        //返回数据
        return ids;
    }
}
